CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   New BoundaryCondition: how to modify a single component of a field? (http://www.cfd-online.com/Forums/openfoam-programming-development/100542-new-boundarycondition-how-modify-single-component-field.html)

look86 April 26, 2012 13:35

New BoundaryCondition: how to modify a single component of a field?
 
hello,
I need to make for a simulation a new type of boundary condition. This is my first attempt of programming with openFoam and I'm able to realize a time varying boundary condition starting from oscillatingFixedValueFvPatchField file.
As in oscillatingBC the field varies with time and it is great for a single component field, such as the pressure p. But if I want to vary only a single component of a velocity field for example, I didn't understand how I can do that. I Understood that the field class belongs from List class, and so I tried with a for cycle and edit one by one all the elements of the list (field), but if I try to reach the x() y() or z() method of the single element I get an error because only the vector class have these method..
so how I can reach this method and vary single component of element of the field list?

best regards and sorry for my bad english

Lucio

Hisham April 26, 2012 13:50

Hi Lucio

All BCs in OF are templated, which means they work for scalars, vectors and tensors in the same fashion. If you elaborate more on your problem, maybe you'll receive better answers!

The cyclic BC will apply the same calculation to all elements of your variable (e.g. a Vector).

If you need to make a BC that works only for one component of a vector, you may consider using codedFixedValue, groovyBC or change the patch from inside the solver.

Regards,
Hisham

look86 April 27, 2012 12:00

thank you very much for the reply! However I reach up a solution with this function in my new BC timeVaryingVelocityComponent :)


Code:

template<class Type>
Field<Type> timeVaryingVelocityComponentFvPatchField<Type>::modRefValue()

{

        Field<Type> copy_(refValue_);
        List<scalar> l_(refValue_.size());
        direction d(component_);
        List< typename Field<Type>::cmptType> Comp_(copy_.component(d));
        label k(searchMax());
 


        for (label i=0; i<l_.size(); i++)
        {
                l_[i]=Comp_[i]*currentScale(Comp_[k]);
        }

        copy_.replace(d,l_);

        return copy_;
}


In this code I modified only the single component (indicated by the int value component_) and I leave untouched the other..

and finally the function searchMax that give the index of the field that points to biggest value between the single component field:

Code:


template <class Type>
label  timeVaryingVelocityComponentFvPatchField<Type>::searchMax()

{
        label maxIndex(0);
        direction d(component_);
        List< typename Field<Type>::cmptType > Comp_refValue_.component(d));

        for (label i=0; i<refValue_.size(); i++)
        {
                if (Comp_[i]>=Comp_[maxIndex]) maxIndex=i;
        }

        return maxIndex;

}

I'm sure, It's nor the best neither the more elegant solution, but It works and for uniform and nonuniform velocity field!
critiques & suggestions are always welcome :)

Best regards,

Lucio

look86 April 28, 2012 10:22

Hello!
I don't know why, but for parallel application this construct works fine:

Code:




template<class Type>
Field<Type> timeVaryingVelocityComponentFvPatchField<Type>::modRefValue()

{

        Field<Type> copy_(refValue_);
        List<scalar> l_(refValue_.size());
        direction d(component_);
        List< typename Field<Type>::cmptType> Comp_(copy_.component(d));
        label k(searchMax());
 


        for (label i=0; i<l_.size(); i++)
        {
                l_[i]=Comp_[i]*currentScale(Comp_[k]);
        }

        copy_.replace(d,l_);

        return copy_;
}


but this other gives me always Fatal error from first iteration!

Code:


template<class Type>
Field<Type> timeVaryingVelocityComponentFvPatchField<Type>::modRefValue()

{

        Field<Type> copy_(refValue_);
        List<scalar> l_(refValue_.size());
        direction d(component_);
        List< typename Field<Type>::cmptType> Comp_(copy_.component(d));
        label k(searchMax());

//************modified part************************\\
        scalar curr_(currentScale(Comp_[k]));
//************************************************\\ 


        for (label i=0; i<l_.size(); i++)
        {

//****************modified part**********************\\
                l_[i]=Comp_[i]*curr_;
//*************************************************\\
        }

        copy_.replace(d,l_);

        return copy_;
}

this error occurs only in parallel process (mpirun -np 4 "solver" -parallel) but if I remove the option -parallel it works fine (but not in parallel I suppose :( ). Indeed the second way is more efficient because I don't call the function currentScale() every step of the loop!
can anybody give me some explanation?

Regard,
Lucio

roucho August 28, 2012 16:48

Standard C++ notes:
1- Make sure that the "currentScale(...)" you invoke returns a scalar
2- Try the parallelized "forAll(...,...)" instead of the classic "for(i=0;...;i++)"


All times are GMT -4. The time now is 23:01.